/**
 * @fileOverview 调整大小
 * @author <a href="mailto:lexloo@126.com">lexloo</a>
 */

(function() {
	if (typeof $XResizer != 'undefined') {
		return;
	}

	$Namespace('com.firefly');

	/**
	 * 调整对象大小
	 * 
	 * @class 调整对象大小
	 * @version 1.0
	 * @author <a href="mailto:lexloo@126.com">lexloo</a>
	 * @constructor
	 */
	com.firefly.XResizer = function(config) {
		this.initialize(config);
	};

	$Lang.apply(com.firefly.XResizer.prototype, {
		enabled : true,
		mouseX : 0,
		mouseY : 0,
		lastMouseX : 0,
		lastMouseY : 0,
		minWidth : 10,/* 最小尺寸 */
		minHeight : 10,
		mOffX : 0,
		mOffY : 0,
		minLeft : 0,
		maxLeft : 9999,
		minTop : 0,
		maxTop : 9999,
		elmX : 0,
		elmY : 0, /* 元素位置 */
		elmW : 0,
		elmH : 0, /* 元素大小 */
		zIndex : 100,
		/**
		 * 调整大小节点类正则表达式检测串
		 */
		__H_REG_CLS : /-([wnes]{2})/,
		/**
		 * 界面代理
		 */
		uiDelegate : null,

		/**
		 * 拖动代理
		 */
		dragDelegate : null,

		/**
		 * showGosht 拖动时显示虚影,默认为false
		 */
		showGhost : false,

		/**
		 * isResizing 是否在调整大小
		 */
		isResizing : false,
		/**
		 * 跟踪对象
		 */
		trackObj : null,
		/**
		 */
		initialize : function(config) {
			var div = $E( {
				tag : 'div',
				className : 'x-resizer-div'
			});

			var eleHTML = '<div class=\"x-resizer-el x-resizer-nw\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-nn\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-ne\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-ww\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-ee\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-sw\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-ss\"></div>';
			eleHTML += '<div class=\"x-resizer-el x-resizer-se\"></div>';

			div.innerHTML = eleHTML;
			$Dom.setStyle(div, 'position', 'absolute');
			$Dom.getBody().appendChild(div);

			this.uiDelegate = div;

			this.initEvents();

			if (config) {
				this.showGhost = (config.showGhost == true) ? true : false;
			}
		},

		/**
		 * 重定位
		 */
		reposition : function() {
			with (this) {
				if (trackObj) {
					var style = $Dom.getCurrentStyle(trackObj);

					$Lang.apply(uiDelegate.style, {
						left : style.left,
						top : style.top,
						width : style.width,
						height : style.height
					});
				}
			}
		},

		/**
		 * 给容器初始化事件
		 * 
		 * @param {Object}
		 *            container 容器
		 */
		initEvents : function() {
			$XEvent.addListener(document, 'mousedown', this.mouseDown.bindAsEventListener(this));
			$XEvent.addListener(document, 'mousemove', this.mouseMove.bindAsEventListener(this));
			$XEvent.addListener(document, 'mouseup', this.mouseUp.bindAsEventListener(this));
		},

		mouseDown : function(evt) {
			this.isResizing = false;

			if ($XEvent.isConsumed(evt)) {
				return;
			}

			var el = $XEvent.getSource(evt);
			while (el) {
				var cls = el.className;

				if (cls && this.__H_REG_CLS.test(cls) && (el.parentNode == this.uiDelegate)) {
					this.dragDelegate = el;
					this.isResizing = true;
					break;
				}

				el = el.parentNode;
			}

			if (!this.isResizing) {
				return;
			}

			if (this.showGhost) {
				$Dom.addClass(this.uiDelegate, 'x-resizer-ghost');
				$Dom.setStyle(this.uiDelegate, 'zIndex', 99999);
			}

			/* 保留当前鼠标位置 */
			this.lastMouseX = $XEvent.pageX(evt);
			this.lastMouseY = $XEvent.pageY(evt);
			this.startResize();

			$XEvent.consume(evt);
		},

		mouseMove : function(evt) {
			if ((!this.isResizing) || ($XEvent.isConsumed(evt))) {
				return;
			}

			with (this) {
				if ((!enabled) || (!dragDelegate)) {
					return;
				}

				/* 保留当前鼠标位置 */
				mouseX = $XEvent.pageX(evt);
				mouseY = $XEvent.pageY(evt);

				/* 计算相对位置 */
				var diffX = mouseX - lastMouseX + mOffX;
				var diffY = mouseY - lastMouseY + mOffY;

				mOffX = mOffY = 0;

				/* 更新鼠标最后位置 */
				lastMouseX = mouseX;
				lastMouseY = mouseY;

				resize(diffX, diffY);

				with (uiDelegate.style) {
					left = elmX + 'px';
					width = elmW + 'px';
					top = elmY + 'px';
					height = elmH + 'px';
				}

				if (!showGhost) {
					resizeTrackObj();
				}
			}

			$XEvent.consume(evt);
		},

		mouseUp : function(evt) {
			with (this) {
				if ((!isResizing) || ($XEvent.isConsumed(evt))) {
					return;
				}

				if (!enabled) {
					return;
				}

				if (showGhost) {
					resizeTrackObj();
				}

				isResizing = false;

				if (this.showGhost) {
					$Dom.removeClass(this.uiDelegate, 'x-resizer-ghost');
					$Dom.setStyle(this.uiDelegate, 'zIndex', 1);
				}

				mOffX = 0;
				mOffY = 0;
			}

			$XEvent.consume(evt);
		},

		/**
		 * 选择元素
		 * 
		 * @param elem
		 *            {DOMElement} 拖动元素
		 */
		startResize : function() {
			if (!this.enabled) {
				return;
			}

			var elem = this.uiDelegate;
			if (!elem)
				return;

			/* elem.style.zIndex = ++this.zIndex; */

			/* 显示拖动范围 */
			this.elmX = parseInt(elem.style.left);
			this.elmX = isNaN(this.elmX) ? 0 : this.elmX;

			this.elmY = parseInt(elem.style.top);
			this.elmY = isNaN(this.elmY) ? 0 : this.elmY;

			this.elmW = elem.offsetWidth;
			this.elmH = elem.offsetHeight;
		},

		/**
		 * 调整大小
		 */
		resize : function(diffX, diffY) {
			with (this) {
				var cls = dragDelegate.className;
				cls = cls.match(__H_REG_CLS) ? RegExp.$1 : '';

				dY = diffY, dX = diffX;

				if (cls.indexOf('n') >= 0) {
					if (elmH - dY < minHeight)
						mOffY = (dY - (diffY = elmH - minHeight));
					else if (elmY + dY < minTop)
						mOffY = (dY - (diffY = minTop - elmY));
					elmY += diffY;
					elmH -= diffY;
				}

				if (cls.indexOf('s') >= 0) {
					if (elmH + dY < minHeight)
						mOffY = (dY - (diffY = minHeight - elmH));
					else if (elmY + elmH + dY > maxTop)
						mOffY = (dY - (diffY = maxTop - elmY - elmH));
					elmH += diffY;
				}

				if (cls.indexOf('w') >= 0) {
					if (elmW - dX < minWidth)
						mOffX = (dX - (diffX = elmW - minWidth));
					else if (elmX + dX < minLeft)
						mOffX = (dX - (diffX = minLeft - elmX));
					elmX += diffX;
					elmW -= diffX;
				}

				if (cls.indexOf('e') >= 0) {
					if (elmW + dX < minWidth)
						mOffX = (dX - (diffX = minWidth - elmW));
					else if (elmX + elmW + dX > maxLeft)
						mOffX = (dX - (diffX = maxLeft - elmX - elmW));
					elmW += diffX;
				}
			}
		},

		/**
		 * 调整Resize对象大小
		 */
		resizeTrackObj : function() {
			with (this) {
				if (trackObj) {
					var style = uiDelegate.style;
					$Lang.apply(trackObj.style, {
						left : style.left,
						top : style.top,
						width : style.width,
						height : style.height
					});
				}
			}
		}

	});
	/**
	 * 设置可见性
	 * 
	 * @param {Boolean}
	 *            visible 可见性
	 */
	com.firefly.XResizer.prototype.setVisible = function(visible) {
		$Dom.setVisible(this.uiDelegate, visible, 'inline');
	},

	/**
	 * 获取可见性
	 */
	com.firefly.XResizer.prototype.getVisible = function() {
		return $Dom.getVisible(this.uiDelegate);
	},

	/**
	 * 跟踪对象
	 * 
	 * @param {HTMLElement}
	 *            obj obj对象
	 */
	com.firefly.XResizer.prototype.track = function(obj) {
		with (this) {
			trackObj = $(obj);

			reposition();
		}
	},

	/**
	 * 
	 * 释放对象
	 */
	com.firefly.XResizer.prototype.dispose = function() {
		$Dom.getBody().removeChild(this.uiDelegate);
	};

	/**
	 * com.firefly.XResizer的快捷访问
	 */
	$XResizer = com.firefly.XResizer;
})();